
#include <BStyle>
#include <BReadWrite>
#include <BShortcut>
#include <BEntry>
#include <BFolder>
#include <BLabel>
#include <BPainter>
#include <BListItem>
#include <BHBoxLayout>
#include <BVBoxLayout>
#include <BGridLayout>
#include <BMessageBox>
#include <BHtmlWidget>
#include <BSplitButton>
#include <BCursor>
#include <BSystem>
#include <BApplication>

#include "Config.h"
#include "PageSettingDialog.h"
#include "XmlTreeWidget.h"
#include "MainWindow.h"

MainWindow::MainWindow()
{
	BShortcut* saveShortcut = new BShortcut("CTRL+S", this);
	BShortcut* saveAllShortcut = new BShortcut("ctrl+shift+s", this);
	connect(saveShortcut, Signal_Triggered, &MainWindow::slotSaveShortcutTriggered);
	connect(saveAllShortcut, Signal_Triggered, &MainWindow::slotSaveAllShortcutTriggered);

	_pathSettingDialog = new PathSettingDialog(this);
	_fileDialog = new BFileDialog(this);
	_checkDialog = new CheckDialog(this);
	_checkDialog->setSize(800, 600);
	_customTagDialog = new CustomTagDialog(this);

	_fileListMenu = new BMenu(this);
	_fileListMenu->setName("list");
	_fileListMenu->addAction("open");
	_fileListMenu->addAction("fresh");
	_fileListMenu->addAction("check");

	_tableMenu = new BMenu(this);
	_tableMenu->setName("table");
	_tableMenu->addSeparator();
	_tableMenu->addAction("add row")->setName("add-row");
	_tableMenu->addAction("insert row")->setName("insert-row");
	_tableMenu->addAction("remove row")->setName("remove-row");
	_tableMenu->addSeparator();
	_tableMenu->addAction("add column")->setName("add-column");
	_tableMenu->addAction("insert column")->setName("insert-column");
	_tableMenu->addAction("remove column")->setName("remove-column");

	_tabMenu = new BMenu(this);
	_tabMenu->setName("tab");
	_tabMenu->addAction("close");
	_tabMenu->addAction("close all");
	_tabMenu->addAction("close others");

	initMenuBar();

	BHBoxLayout* toolLayout = new BHBoxLayout();
	{
		_openButton = new BButton("open");
		_saveButton = new BButton("save");
		_saveButton->setEnabled(false);
		_saveAllButton = new BButton("save-all");
		_saveAllButton->setEnabled(false);

		_prevButton = new BSplitButton(Form_IconOnly);
		_prevButton->setName("prev");

		_nextButton = new BSplitButton(Form_IconOnly);
		_nextButton->setName("next");

		_editableButton = new BButton("Editable");
		_editableButton->setCheckable(true);

		_editLayout = new BHBoxLayout();
		{
			_editLayout->addWidget(_menuBar);
			_editLayout->addWidget(new BButton(_removeAction));
			_editLayout->addWidget(new BButton(_cutAction));
			_editLayout->addWidget(new BButton(_copyAction));
			_editLayout->addWidget(new BButton(_pasteAction));
		}
		_editLayout->setEnabled(false);

		_viewMenuButton = new BButton("view");
		{
			BMenu* viewMenu = new BMenu();
			viewMenu->setName("view");
			viewMenu->addAction("show-links")->setCheckable(true);
			viewMenu->addAction("show-break")->setCheckable(true);
			viewMenu->addAction("show-manager")->setCheckable(true);
			viewMenu->addAction("page-setting");

			_viewMenuButton->setMenu(viewMenu);
		}

		BLabel* languageLable = new BLabel("language");
		languageLable->setAlign(Align_RightCenter);
		_languageComboBox = new BComboBox();

		toolLayout->addWidget(_openButton);
		toolLayout->addWidget(_saveButton);
		toolLayout->addWidget(_saveAllButton);
		toolLayout->addSpring(10);
		toolLayout->addWidget(_prevButton);
		toolLayout->addWidget(_nextButton);
		toolLayout->addSpring(10);
		toolLayout->addWidget(_editableButton);
		toolLayout->addSpacer(10);
		toolLayout->addLayout(_editLayout);
		toolLayout->addSpring(10);
		toolLayout->addWidget(_viewMenuButton);
		toolLayout->addSpacer(10);
		toolLayout->addWidget(languageLable);
		toolLayout->addWidget(_languageComboBox);
	}

	_tabWidget = new BTabWidget("left");
	_tabWidget->setTabPart(Part_Bottom);
	{
		BHBoxLayout* bottomLayout = new BHBoxLayout(_tabWidget, Part_Bottom);
		{
			_hideButton = new BButton(Graph_Cross);
			_hideButton->setName("list-hide");
			_hideButton->setIconSize(10);
			bottomLayout->addSpring();
			bottomLayout->addWidget(_hideButton);
		}

		_fileListWidget = new BListWidget("File List");
		_fileListWidget->setName("head-list");
		_fileListWidget->setSelectMode(Select_Single);
		_fileListWidget->setAreaPolicy(Policy_Growing, Policy_Preferred);
		{
			BHBoxLayout* topLayout = new BHBoxLayout(_fileListWidget, Part_Top);
			BMenu* iconMenu = new BMenu();
			iconMenu->setName("icon-info");
			_itemStateButton = new BButton();
			_itemStateButton->setName("item-state");
			_itemStateButton->setMenu(iconMenu);
			_itemStateButton->setForm(Form_IconOnly);

			_headFreshButton = new BButton(Form_IconAlone);

			topLayout->addSpring();
			topLayout->addWidget(_itemStateButton);
			topLayout->addWidget(_headFreshButton);
		}

		_htmlTreeWidget = new BTreeWidget("Hierarchy");
		_htmlTreeWidget->setName("hierarchy");
		_htmlTreeWidget->setTitleVisible(true);
		_htmlTreeWidget->setSelectMode(Select_Single);

		_tabWidget->addTab(_fileListWidget);
		_tabWidget->addTab(_htmlTreeWidget);
	}

	_pageTabWidget = new BTabWidget("pages");
	_propertyBoard = new PropertyBoard();
	_propertyBoard->setVisible(true);

	BHBoxLayout* splitLayout = new BHBoxLayout();
	splitLayout->setSplitable(true);
	splitLayout->setSpacing(6);
	splitLayout->addWidget(_tabWidget, 100);
	splitLayout->addWidget(_pageTabWidget, 800);
	splitLayout->addWidget(_propertyBoard, 100);

	_statusBar = new BStatusBar();

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(toolLayout, 0);
	vlayout->addLayout(splitLayout);
	vlayout->addWidget(_statusBar, 0);

	connect(_fileListMenu, Signal_Triggered, &MainWindow::slotHeadListMenuTrigger);
	connect(_tableMenu, Signal_Triggered, &MainWindow::slotTableMenuTrigger);
	connect(_tabMenu, Signal_Triggered, &MainWindow::slotTabMenuTrigger);

	connect(_viewMenuButton->menu(), Signal_Styled, &MainWindow::slotMenuStyled);
	connect(_fileListMenu, Signal_Styled, &MainWindow::slotMenuStyled);

	connect(_openButton, Signal_Clicked, &MainWindow::slotOpenDocument);
	connect(_saveButton, Signal_Clicked, &MainWindow::slotSaveDocument);
	connect(_saveAllButton, Signal_Clicked, &MainWindow::slotSaveAllDocument);
	connect(_prevButton, Signal_Clicked, &MainWindow::slotSaveAllDocument);

	connect(_headFreshButton, Signal_Clicked, &MainWindow::slotFreshButtonClicked);
	connect(_viewMenuButton->menu(), Signal_Triggered, &MainWindow::slotViewMenuTriggered);
	connect(_editableButton, Signal_Toggled, &MainWindow::slotEditableButtonToggled);
	connect(_languageComboBox, Signal_CurrentChanged, &MainWindow::slotLanguageCurrentChanged);

	connect(_tabWidget, Signal_Hide, &MainWindow::slotTabWidgetHide);
	connect(_hideButton, Signal_Clicked, &MainWindow::slotHideButtonClicked);

	connect(_fileListWidget, Signal_ItemDoubleClicked, &MainWindow::slotHeadItemDoubleClicked);
	connect(_fileListWidget, Signal_ItemRightClicked, &MainWindow::slotHeadItemRightClicked);
	connect(_fileListWidget, Signal_Framed, &MainWindow::slotHeadListWidgetFramed);

	connect(_htmlTreeWidget, Signal_ItemClicked, &MainWindow::slotHtmlTreeItemClicked);
	connect(_htmlTreeWidget, Signal_KeyPress, &MainWindow::slotHtmlTreeWidgetKeyPress);

	connect(_pageTabWidget, Signal_Framed, &MainWindow::slotTabWidgetFramed);
	connect(_pageTabWidget, Signal_CurrentChanged, &MainWindow::slotTabCurrentChanged);
	connect(_pageTabWidget, Signal_TabClosing, &MainWindow::slotTabClosing);
	connect(_pageTabWidget, Signal_TabHovered, &MainWindow::slotTabHovered);
	connect(_pageTabWidget, Signal_TabClicked, &MainWindow::slotTabClicked);
	connect(_pageTabWidget, Signal_TabRightClicked, &MainWindow::slotTabRightClicked);

	connect(_propertyBoard, Signal_Changed, &MainWindow::slotPropertyBoardChanged);

	_languageComboBox->addItem("chinese");
	_languageComboBox->addItem("english");

	if (Config* config = BApplication::property("config"))
	{
		_languageComboBox->setText(config->language());
		connect(config, Signal_Changed, &MainWindow::slotConfigChanged);
	}
	_viewMenuButton->menu()->action("show-manager")->setChecked(true);
}
MainWindow::~MainWindow()
{
	if (Config* config = BApplication::property("config"))
	{
		if (config->isDirty())
			config->save();
	}
}

bool MainWindow::openHtmlFile(const BString& fileName)
{
	BString title = fileName.name();
	title -= ".html";

	if (BWidget* widget = _pageTabWidget->namedTab(fileName))
	{
		_pageTabWidget->setCurrent(widget);
		return true;
	}

	if (!BFile::Exist(fileName))
		return false;

	BHtmlWidget* htmlWidget = new BHtmlWidget();
	if (!htmlWidget->load(fileName))
	{
		htmlWidget->setBody(new BHtmlItem("body"));
	}

	htmlWidget->setName(fileName);
	htmlWidget->setTitle(title);
	htmlWidget->setIcon(_htmlIcon);
	if (Config* config = BApplication::property("config"))
	{
		htmlWidget->setScrollStep(config->scrollStep());
		htmlWidget->setSpreadSize(config->spreadSize());
	}

	_pageTabWidget->addTab(htmlWidget, true);
	_pageTabWidget->setCurrent(htmlWidget);

	connect(htmlWidget, Signal_ItemChanged, &MainWindow::slotHtmlItemChanged);
	connect(htmlWidget, Signal_ItemClicked, &MainWindow::slotHtmlItemClicked);
	connect(htmlWidget, Signal_ItemRightClicked, &MainWindow::slotHtmlItemRightClicked);
	return true;
}

void MainWindow::initMenuBar()
{
	BMenu* headMenu = new BMenu("head");
	headMenu->addAction("h1");
	headMenu->addAction("h2");
	headMenu->addAction("h3");
	headMenu->addAction("h4");
	headMenu->addAction("h5");
	headMenu->addAction("h6");

	BMenu* textMenu = new BMenu("text");
	textMenu->addAction("text");
	textMenu->addAction("pre");
	textMenu->addAction("br");

	BMenu* listMenu = new BMenu("list");
	listMenu->addAction("ul");
	listMenu->addAction("ol");
	listMenu->addAction("dl");

	BAction* pAction = new BAction("p");
	BAction* aAction = new BAction("a");
	BAction* imgAction = new BAction("img");
	BAction* divAction = new BAction("div");
	BAction* tableAction = new BAction("table");
	BAction* customAction = new BAction("custom");
	customAction->setName("custom");

	BMenu* addMenu = new BMenu("Add");
	addMenu->setName("menu-add");
	addMenu->addMenu(headMenu);
	addMenu->addMenu(textMenu);
	addMenu->addAction(pAction);
	addMenu->addAction(aAction);
	addMenu->addAction(imgAction);
	addMenu->addAction(divAction);
	addMenu->addMenu(listMenu);
	addMenu->addAction(tableAction);
	addMenu->addAction(customAction);

	BMenu* prependMenu = new BMenu("Prepend");
	prependMenu->setName("menu-prepend");
	prependMenu->addMenu(headMenu);
	prependMenu->addMenu(textMenu);
	prependMenu->addAction(pAction);
	prependMenu->addAction(aAction);
	prependMenu->addAction(imgAction);
	prependMenu->addAction(divAction);
	prependMenu->addMenu(listMenu);
	prependMenu->addAction(tableAction);
	prependMenu->addAction(customAction);

	BMenu* appendMenu = new BMenu("Append");
	appendMenu->setName("menu-append");
	appendMenu->addMenu(headMenu);
	appendMenu->addMenu(textMenu);
	appendMenu->addAction(pAction);
	appendMenu->addAction(aAction);
	appendMenu->addAction(imgAction);
	appendMenu->addAction(divAction);
	appendMenu->addMenu(listMenu);
	appendMenu->addAction(tableAction);
	appendMenu->addAction(customAction);

	BMenu* convertMenu = new BMenu("Convert");
	convertMenu->setName("menu-convert");
	convertMenu->addMenu(headMenu);
	convertMenu->addMenu(textMenu);
	convertMenu->addAction(pAction);
	convertMenu->addAction(aAction);
	convertMenu->addAction(imgAction);
	convertMenu->addAction(divAction);
	convertMenu->addMenu(listMenu);
	convertMenu->addAction(tableAction);
	convertMenu->addAction(customAction);

	_menuBar = new BMenuBar();
	_menuBar->setSpacing(3);
	_menuBar->addMenu(addMenu);
	_menuBar->addMenu(prependMenu);
	_menuBar->addMenu(appendMenu);
	_menuBar->addMenu(convertMenu);

	_removeAction = new BAction("remove");
	_cutAction = new BAction("cut");
	_copyAction = new BAction("copy");
	_pasteAction = new BAction("paste");

	_pageMenu = new BMenu(this);
	_pageMenu->setName("page");
	_pageMenu->addMenu(addMenu);
	_pageMenu->addMenu(prependMenu);
	_pageMenu->addMenu(appendMenu);
	_pageMenu->addMenu(convertMenu);
	_pageMenu->addSeparator();
	_pageMenu->addAction(_removeAction);
	_pageMenu->addAction(_cutAction);
	_pageMenu->addAction(_copyAction);
	_pageMenu->addAction(_pasteAction);

	connect(addMenu, Signal_ActionClicked, &MainWindow::slotMenuAddActionClicked);
	connect(prependMenu, Signal_ActionClicked, &MainWindow::slotMenuPrependActionClicked);
	connect(appendMenu, Signal_ActionClicked, &MainWindow::slotMenuAppendActionClicked);
	connect(convertMenu, Signal_ActionClicked, &MainWindow::slotMenuConvertActionClicked);

	connect(_removeAction, Signal_Triggered, &MainWindow::slotRemoveActionTriggered);
	connect(_cutAction, Signal_Triggered, &MainWindow::slotCutActionTriggered);
	connect(_copyAction, Signal_Triggered, &MainWindow::slotCopyActionTriggered);
	connect(_pasteAction, Signal_Triggered, &MainWindow::slotPasteActionTriggered);

}
bool MainWindow::checkHeadFile(BListItem* item)
{
	BString headFileName = _includeFolder.path() + '/' + item->text();
	BString htmlFileName = _manualFolder.path() + '/' + item->text() + ".html";
	_checkDialog->openHeadFile(headFileName);
	_checkDialog->loadHtmlFile(htmlFileName);
	if (_checkDialog->execute())
	{
		BEntry* headEntry = BEntry::Open(headFileName);
		item->setProperty("head", headEntry);
		BEntry* htmlEntry = BEntry::Open(htmlFileName);
		item->setProperty("html", htmlEntry);
		freshHtmlFile(htmlFileName);
		return true;
	}
	return false;
}
bool MainWindow::freshHtmlFile(const BString& fileName)
{
	BString title = fileName.name();
	title -= ".html";

	BWidget* widget = _pageTabWidget->tab(title);
	if (!widget)
		return false;

	BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(widget);
	if (!htmlWidget->load(fileName))
		return false;

	_pageTabWidget->setCurrent(htmlWidget);

	return true;
}
void MainWindow::signTitleChanged(BWidget* widget, bool changed)
{
	const BString& title = widget->title();
	if (changed)
	{
		if (title.last() != '*')
		{
			BString newTitle;
			newTitle << title << "*";
			widget->setTitle(newTitle);
		}
	}
	else
	{
		if (title.last() == '*')
		{
			BString newTitle = title - '*';
			widget->setTitle(newTitle);
		}
	}
}
void MainWindow::freshHeadItemIcons(BListItem* item)
{
	item->setIcon(_htmlIcon);
	BEntry* headEntry = item->property("head");
	BEntry* htmlEntry = item->property("html");
	if (htmlEntry)
	{
		const BDate& date0 = htmlEntry->date();
		const BDate& date1 = headEntry->date();
		const BTime& time0 = htmlEntry->time();
		const BTime& time1 = headEntry->time();
		if (htmlEntry->date() > headEntry->date() || htmlEntry->time() > headEntry->time())
			item->setImage(_normalImage);
		else
			item->setImage(_dirtyImage);
	}
	else
	{
		item->setImage(_emptyImage);
	}
}

void MainWindow::resetTreeWidget()
{
	BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(_pageTabWidget->current());
	if (_htmlTreeWidget->asset() != htmlWidget)
	{
		_htmlTreeWidget->clearItems();
		if (htmlWidget)
		{
			BTreeItem* bodyItem = createTreeItem(htmlWidget->body());
			_htmlTreeWidget->addItem(bodyItem);
			freshTreeItemIcon(bodyItem);
		}
		_htmlTreeWidget->setAsset(htmlWidget);
	}
}
BTreeItem* MainWindow::createTreeItem(BHtmlItem* htmlItem)
{
	BTreeItem* treeItem = new BTreeItem(htmlItem->name());
	treeItem->setAsset(htmlItem);
	for (int i = 0; i < htmlItem->childCount(); i++)
	{
		BHtmlItem* child = htmlItem->child(i);
		BTreeItem* childItem = createTreeItem(child);
		treeItem->addChild(childItem);
	}
	return treeItem;
}
void MainWindow::refreshTreeItem(BHtmlItem* htmlItem)
{
	if (!_htmlTreeWidget)
		return;
	if (BTreeItem* treeItem = _htmlTreeWidget->itemOfAsset(htmlItem))
	{
		treeItem->clearChildren();
		for (int i = 0; i < htmlItem->childCount(); i++)
		{
			BHtmlItem* child = htmlItem->child(i);
			BTreeItem* childItem = createTreeItem(child);
			treeItem->addChild(childItem);
		}
		freshTreeItemIcon(treeItem);
	}
}
void MainWindow::freshTreeItemIcon(BTreeItem* item)
{
	const BStyle* style = this->realStyle();
	if (item->text().empty())
	{
		BIcon* icon = style->icon("text");
		item->setIcon(icon);
	}
	else
	{
		BIcon* icon = style->icon(item->text());
		item->setIcon(icon);
	}
	for (int i = 0; i < item->childCount(); i++)
	{
		BTreeItem* child = item->child(i);
		freshTreeItemIcon(child);
	}
}
void MainWindow::paintLinks(BHtmlItem* item, BPainter& painter)
{
	if (item->containAttrib("id"))
	{
		const BString& id = item->attrib("id");
		BImage* image = _linkIcon->image();
		BSize size = image->size();
		const BRect& rect = item->rect();
		BRect imageRect(rect.leftTop() + BPoint(0, -size.height() / 2), size);
		painter.drawImage(imageRect, _linkIcon->image());
		painter.setColor(200, 0, 0);
		painter.drawLine(rect.leftTop(), imageRect.leftTop());
	}
	for (int i = 0; i < item->childCount(); i++)
	{
		BHtmlItem* child = item->child(i);
		paintLinks(child, painter);
	}
}
void MainWindow::paintMarks(BHtmlItem* item, BPainter& painter)
{
	BMenu* viewMenu = _viewMenuButton->menu();
	if (item->name() == "br" && viewMenu->action("show-break")->checked())
	{
		BRect rect = item->rect();
		rect = rect.align(Align_BottomCenter, bMin(rect.width(), rect.height()));
		if (!painter.clip().intersect(rect))
			return;
		rect %= 60;
		painter.setColor(200, 0, 0);
		painter.setLineSmooth(true);
		painter.drawLine(rect.rightTop(), rect.rightBottom());
		painter.drawLine(rect.leftBottom(), rect.rightBottom());
		int x = rect.left() + 5;
		int y0 = rect.bottom() - 5;
		int y1 = rect.bottom() + 5;
		painter.drawLine(rect.leftBottom(), BPoint(x, y0));
		painter.drawLine(rect.leftBottom(), BPoint(x, y1));
		painter.setLineSmooth(false);
	}
	for (int i = 0; i < item->childCount(); i++)
	{
		BHtmlItem* child = item->child(i);
		paintMarks(child, painter);
	}
}
void MainWindow::paintUnderLine(BHtmlItem* item, BPainter& painter)
{
	if (item->text().empty())
	{
		BRect itemRect = item->rect();
		BPoint p0 = itemRect.leftBottom();
		BPoint p1 = itemRect.rightBottom();
		painter.drawLine(p0, p1);
	}
	else
	{
		BPoint begin = item->cellRect(0).leftBottom();
		BPoint end = item->cellRect(0).rightBottom();
		for (int i = 1; i < item->cellCount(); i++)
		{
			const BRect& rect = item->cellRect(i);
			BPoint point = rect.rightBottom();
			if (i == item->cellCount() - 1)
			{
				painter.drawLine(begin, point);
				break;
			}
			if (point.y() != begin.y())
			{
				painter.drawLine(begin, end);
				begin = rect.leftBottom();
				end = rect.leftBottom();
				continue;
			}
			end = point;
		}
	}
}

void MainWindow::slotHeadListMenuTrigger(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (!action)
		return;
	const BString& text = action->text();
	if (text == "open")
	{
		if (BListItem* item = _fileListWidget->selectedItem())
		{
			BEntry* htmlEntry = item->property("html");
			const BString& htmlName = htmlEntry->path();
			if (!BFile::Exist(htmlName))
			{
				BString text = htmlName;
				text << ".html is not exist.\nPlease create docment first.";
				Button result = BMessageBox::Information(this, "Question", text);
				return;
			}
			if (!openHtmlFile(htmlName))
			{
				BString text("Open html file ");
				text << htmlName << ".html Failed.";
				Button result = BMessageBox::Warning(this, "Question", text);
				return;
			}
		}
		return;
	}
	if (text == "fresh")
	{
		return;
	}
	if (text == "check")
	{
		if (BListItem* item = _fileListWidget->selectedItem())
		{
			checkHeadFile(item);
			freshHeadItemIcons(item);
		}
		return;
	}
}
void MainWindow::slotTableMenuTrigger(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (!action)
		return;
	BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(_pageTabWidget->current());
	if (!htmlWidget)
		return;
	BHtmlItem* item = htmlWidget->selectedItem();
	if (!item)
		return;
	if (item->name() == "table")
	{
		int columnCount = 0;
		for (int r = 0; r < item->childCount(); r++)
		{
			BHtmlItem* rowItem = item->child(r);
			if (columnCount < rowItem->childCount())
				columnCount = rowItem->childCount();
		}

		if (action->name() == "add-row")
		{
			BHtmlItem* rowItem = new BHtmlItem("tr");
			rowItem->setFormat("\n<");
			for (int c = 0; c < columnCount; c++)
				rowItem->addChild(new BHtmlItem("td"));
			item->addChild(rowItem);
			return;
		}
		if (action->name() == "add-column")
		{
			for (int i = 0; i < item->childCount(); i++)
			{
				BHtmlItem* rowItem = item->child(i);
				rowItem->addChild(new BHtmlItem("td"));
			}
		}
		return;
	}
	if (item->name() == "tr")
	{
		BHtmlItem* table = item->parent("table");
		int row = 0;
		int columnCount = 0;
		for (int r = 0; r < table->childCount(); r++)
		{
			BHtmlItem* rowItem = table->child(r);
			if (columnCount < rowItem->childCount())
				columnCount = rowItem->childCount();
			if (rowItem == item)
			{
				row = r;
				break;
			}
		}
		if (action->name() == "add-row")
		{
			BHtmlItem* rowItem = new BHtmlItem("tr");
			rowItem->setFormat("\n<");
			for (int c = 0; c < columnCount; c++)
				rowItem->addChild(new BHtmlItem("td"));
			table->addChild(rowItem);
			return;
		}
		if (action->name() == "insert-row")
		{
			BHtmlItem* rowItem = new BHtmlItem("tr");
			rowItem->setFormat("\n<");
			for (int c = 0; c < columnCount; c++)
				rowItem->addChild(new BHtmlItem("td"));
			table->insertChild(row, rowItem);
			return;
		}
		if (action->name() == "remove-row")
		{
			table->removeChild(row);
			return;
		}
		if (action->name() == "add-column")
		{
			for (int r = 0; r < table->childCount(); r++)
			{
				BHtmlItem* rowItem = table->child(r);
				rowItem->addChild(new BHtmlItem("td"));
			}
			return;
		}
	}
	if (item->name() == "td")
	{
		BHtmlItem* table = item->parent("table");
		int row = 0;
		int column = 0;
		int columnCount = 0;
		for (int r = 0; r < table->childCount(); r++)
		{
			BHtmlItem* rowItem = table->child(r);
			if (columnCount < rowItem->childCount())
				columnCount = rowItem->childCount();
			for (int c = 0; c < rowItem->childCount(); c++)
			{
				BHtmlItem* tdItem = rowItem->child(c);
				if (tdItem == item)
				{
					row = r;
					column = c;
					break;
				}
			}
		}
		if (action->name() == "add-row")
		{
			BHtmlItem* rowItem = new BHtmlItem("tr");
			rowItem->setFormat("\n<");
			for (int c = 0; c < columnCount; c++)
				rowItem->addChild(new BHtmlItem("td"));
			table->addChild(rowItem);
			return;
		}
		if (action->name() == "insert-row")
		{
			BHtmlItem* rowItem = new BHtmlItem("tr");
			rowItem->setFormat("\n<");
			for (int c = 0; c < columnCount; c++)
				rowItem->addChild(new BHtmlItem("td"));
			table->insertChild(row, rowItem);
			return;
		}
		if (action->name() == "remove-row")
		{
			table->removeChild(row);
			return;
		}
		if (action->name() == "add-column")
		{
			for (int r = 0; r < table->childCount(); r++)
			{
				BHtmlItem* rowItem = table->child(r);
				rowItem->addChild(new BHtmlItem("td"));
			}
			return;
		}
		if (action->name() == "insert-column")
		{
			for (int r = 0; r < table->childCount(); r++)
			{
				BHtmlItem* rowItem = table->child(r);
				rowItem->insertChild(column, new BHtmlItem("td"));
			}
			return;
		}
		if (action->name() == "remove-column")
		{
			for (int r = 0; r < table->childCount(); r++)
			{
				BHtmlItem* rowItem = table->child(r);
				rowItem->removeChild(column);
			}
			return;
		}
	}
}
void MainWindow::slotTabMenuTrigger(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (action->text() == "close")
	{
		BWidget* widget = _pageTabWidget->current();
		_pageTabWidget->removeTab(widget);
		return;
	}
	if (action->text() == "close all")
	{
		_pageTabWidget->clearTabs();
	}
	if (action->text() == "close others")
	{
		BWidget* current = _pageTabWidget->current();
		for (int i = 0; i < _pageTabWidget->tabCount(); i++)
		{
			BWidget* widget = _pageTabWidget->tab(i);
			if (widget != current)
			{
				_pageTabWidget->removeTab(i--);
			}
		}
	}
}

void MainWindow::slotConfigChanged()
{
	if (Config* config = BApplication::property("config"))
	{
		for (int i = 0; i < _pageTabWidget->tabCount(); i++)
		{
			BHtmlWidget* htmlWidget = (BHtmlWidget*)_pageTabWidget->tab(i);
			htmlWidget->setScrollStep(config->scrollStep());
			htmlWidget->setSpreadSize(config->spreadSize());
		}
	}
}

void MainWindow::slotSaveShortcutTriggered(BObject* object, const BValue& value)
{
	slotSaveDocument();
}
void MainWindow::slotSaveAllShortcutTriggered(BObject* object, const BValue& value)
{
	slotSaveAllDocument();
}

void MainWindow::slotOpenDocument()
{
	BString fileName = BFileDialog::OpenFile(0, "Open html file", _languageComboBox->value(), "*.html");
	if (fileName.size())
	{
		if (openHtmlFile(fileName))
		{
			_htmlTreeWidget->show();
		}
		else
		{
			BString text("Open html file ");
			text << fileName + " Failed.";
			Button result = BMessageBox::Warning(this, "Question", text);
		}
	}
}
void MainWindow::slotSaveDocument()
{
	BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(_pageTabWidget->current());
	if (htmlWidget && htmlWidget->title().endWith('*'))
	{
		if (!htmlWidget->save(htmlWidget->name()))
		{
			BString text("Save html file ");
			text << htmlWidget->name() << " Failed.";
			BMessageBox::Critical(this, "Critical", text);
		}
		else
		{
			signTitleChanged(htmlWidget, false);
		}
	}
}
void MainWindow::slotSaveAllDocument()
{
	for (int i = 0; i < _pageTabWidget->tabCount(); i++)
	{
		BWidget* tab = _pageTabWidget->tab(i);
		BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(tab);
		if (!htmlWidget || htmlWidget->title().last() != '*')
			continue;
		if (htmlWidget->save(htmlWidget->name()))
			signTitleChanged(htmlWidget, false);
	}
}
void MainWindow::slotLanguageCurrentChanged(BObject* object, const BValue& value)
{
	BApplication::cleanTranslation();
	const BString& language = _languageComboBox->text();
	BString sheetFileName("data/language/");
	sheetFileName << language << "/docgen.css";
	BApplication::addStyleSheet(sheetFileName);
	if (Config* config = BApplication::property("config"))
	{
		config->setLanguage(language);
	}
}

void MainWindow::slotHideButtonClicked()
{
	_tabWidget->hide();
}
void MainWindow::slotTabWidgetHide(BListWidget* listWidget, const BValue& value)
{
	_viewMenuButton->menu()->action("show-manager")->setChecked(false);
}

void MainWindow::slotFreshButtonClicked(BButton* button)
{
	_pathSettingDialog->setIcon(button->icon());
	if (!_pathSettingDialog->execute())
		return;

	_includeFolder.setPath(_pathSettingDialog->headerPath());
	if (_includeFolder.open() == false)
		return;

	const BString& language = _languageComboBox->text();
	_manualFolder.setPath(_pathSettingDialog->manualPath() + '/' + language);
	if (!_manualFolder.open())
	{
		_manualFolder.setPath(_pathSettingDialog->manualPath());
		_manualFolder.open();
	}
	if (!_manualFolder.isOpened())
		return;

	_fileListWidget->clearItems();
	for (int i = 0; i < _includeFolder.entryCount(); i++)
	{
		BEntry* entry = _includeFolder.entry(i);
		if (entry->attrib() & Attrib_File)
		{
			BListItem* item = _fileListWidget->addItem(entry->name());
			item->setProperty("head", entry);
			BString htmlEntryName = entry->name() + ".html";
			BEntry* htmlEntry = _manualFolder.entry(htmlEntryName);
			item->setProperty("html", htmlEntry);
			freshHeadItemIcons(item);
		}
	}
	_fileListWidget->show();
}
void MainWindow::slotHeadItemRightClicked(BObject* object, const BValue& value)
{
	BListItem* item = value;
	if (!item)
		return;
	const BPoint& point = BCursor::GetPos();
	BPoint pos = point - this->pos();
	_fileListMenu->setPos(pos);
	_fileListMenu->popup();
}
void MainWindow::slotHeadItemDoubleClicked(BObject* object, const BValue& value)
{
	BListItem* item = value;
	if (!item)
		return;
	BEntry* htmlEntry = item->property("html");
	if (htmlEntry)
	{
		const BString& htmlName = htmlEntry->path();
		if (htmlName.empty())
		{
			checkHeadFile(item);
		}
		else
		{
			openHtmlFile(htmlName);
		}
	}
}
void MainWindow::slotHeadListWidgetFramed(BListWidget* listWidget, const BValue& value)
{
	const BListItemArray& items = listWidget->query("visual-items");
	if (items.size())
	{
		BPainter painter(listWidget);
		painter.setClip(listWidget->centerRect());
		for (int i = 0; i < items.size(); i++)
		{
			BListItem* item = items[i];
			if (const BImage* image = item->image())
			{
				BRect imageRect = item->iconRect().align(Align_LeftBottom, BSize(10));
				painter.drawImage(imageRect, image);
			}
		}
	}
}

void MainWindow::slotTabWidgetFramed(BTabWidget* tabWidget, const BValue& value)
{
	BPainter painter(tabWidget);
	BRect rect = tabWidget->tabRect(tabWidget->current());
	rect.top() = rect.bottom();
	rect.bottom() += 3;
	rect.left() += 1;
	rect.right() -= 1;
	painter.fillRect(rect);
}
void MainWindow::slotTabCurrentChanged(BObject* object, const BValue& value)
{
	BHtmlWidget* htmlWidget = value;
	if (BWidget* widget = _propertyBoard->asset())
	{
		disconnect(widget, Signal_Framed);
		disconnect(widget, Signal_KeyPress);
		disconnect(widget, Signal_ItemSelected);
	}
	_propertyBoard->setAsset(htmlWidget);
	if (BWidget* widget = _propertyBoard->asset())
	{
		connect(widget, Signal_Framed, &MainWindow::slotHtmlWidgetFramed);
		connect(widget, Signal_ItemSelected, &MainWindow::slotHtmlItemSelected);
	}
	if (htmlWidget)
	{
		_editableButton->setChecked(htmlWidget->editable());
		_editLayout->setEnabled(htmlWidget->editable());
		BApplication::setCurrentPath(htmlWidget->fileName().path());
	}
	resetTreeWidget();
	_menuBar->setEnabled(htmlWidget);
	_editableButton->setEnabled(htmlWidget);
	_removeAction->setEnabled(htmlWidget);
	_cutAction->setEnabled(htmlWidget);
	_copyAction->setEnabled(htmlWidget);
	_pasteAction->setEnabled(htmlWidget);
}
void MainWindow::slotTabClicked(BObject* object, BValue& value)
{
	BWidget* widget = value;
	if (widget)
	{
		const BString& title = widget->title();
		BListItem* item = _fileListWidget->item(title);
		if (item)
		{
			item->setSelected(true);
			_fileListWidget->scrollToItem(item, Align_VCenter);
		}
		else
		{
			_fileListWidget->clearSelection();
		}
	}
}
void MainWindow::slotTabRightClicked(BObject* object, BValue& value)
{
	BWidget* widget = value;
	const BPoint& point = BCursor::GetPos();
	BPoint pos = point - this->pos();
	_tabMenu->setPos(pos);
	_tabMenu->popup();
}
void MainWindow::slotTabClosing(BObject* object, BValue& value)
{
	BHtmlWidget* htmlWidget = value;
	if (htmlWidget && htmlWidget->title().first() == '*')
	{
		Button btn = BMessageBox::Question(this, "Close Html", "Do you want close the html document ?");
		if (btn == Button_No)
			value = 0;
	}
}
void MainWindow::slotTabHovered(BObject* object, BValue& value)
{
	if (BHtmlWidget* widget = value)
		_pageTabWidget->setTips(widget->fileName());
	else
		_pageTabWidget->setTips(BString());
}

void MainWindow::slotHtmlTreeItemClicked(BObject* object, BValue& value)
{
	if (BTreeItem* item = value)
	{
		BHtmlItem* htmlItem = item->asset();
		htmlItem->htmlWidget()->clearSelection();
		htmlItem->htmlWidget()->scrollToItem(htmlItem, Align_Center);
		htmlItem->setSelected(item->selected());
	}
}
void MainWindow::slotHtmlTreeWidgetKeyPress(BObject* object, BValue& value)
{
	Key key = value;
	if (key == Key_Delete)
	{
		BHtmlWidget* htmlWidget = _propertyBoard->asset();
		const BTreeItemArray& selection = _htmlTreeWidget->selection();
		for (int i = 0; i < selection.size(); i++)
		{
			BTreeItem* item = selection[i];
			htmlWidget->removeItem(item->asset());
			_htmlTreeWidget->removeItem(item);
		}
		const BEvent* event = value.annex<BEvent>();
		event->accept();
	}
}
void MainWindow::slotPropertyBoardChanged(BObject* object, BValue& value)
{
	if (BHtmlWidget* htmlWidget = value)
	{
		signTitleChanged(htmlWidget, true);
	}
}

void MainWindow::slotEditableButtonToggled(BObject* object, const BValue& value)
{
	if (BHtmlWidget* htmlWidget = (BHtmlWidget*)_pageTabWidget->current())
	{
		bool checked = value;
		htmlWidget->setEditable(checked);
		if (checked && !htmlWidget->body())
		{
			htmlWidget->setBody(new BHtmlItem("body"));
			_statusBar->showMessage("html is empty, create body !", 10);
		}
	}
	_editLayout->setEnabled(value);
}
void MainWindow::slotViewMenuTriggered(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (action->text() == "show-manager")
	{
		_tabWidget->setVisible(action->checked());
		return;
	}
	if (action->text() == "page-setting")
	{
		static PageSettingDialog* settingDialog = new PageSettingDialog(this);
		settingDialog->popup();
		return;
	}
	if (BHtmlWidget* htmlWidget = (BHtmlWidget*)_pageTabWidget->current())
	{
		htmlWidget->fresh();
	}
}
void MainWindow::slotMenuStyled(BMenu* menu, const BValue& value)
{
	const BStyle* style = value;
	for (int i = 0; i < menu->count(); i++)
	{
		if (BAction* action = menu->action(i))
		{
			action->setIcon(style->icon(action->text()));
			action->setTips(style->text(action->text()));
		}
	}
}

void MainWindow::slotRemoveActionTriggered(BObject* object, const BValue& value)
{
	if (BHtmlWidget* htmlWidget = (BHtmlWidget*)_pageTabWidget->current())
	{
		if (BHtmlItem* item = htmlWidget->selectedItem())
		{
			if (BTreeItem* treeItem = _htmlTreeWidget->itemOfAsset(item))//remove tree item first;
			{
				_htmlTreeWidget->removeItem(treeItem);
			}
			htmlWidget->removeItem(item);
		}
	}
}
void MainWindow::slotCutActionTriggered(BObject* object, const BValue& value)
{
	if (BHtmlWidget* htmlWidget = (BHtmlWidget*)_pageTabWidget->current())
	{
		if (BHtmlItem* item = htmlWidget->selectedItem())
		{
			BSystem::SetClippedValue(item);
			if (BTreeItem* treeItem = _htmlTreeWidget->itemOfAsset(item))//remove tree item first;
			{
				_htmlTreeWidget->removeItem(treeItem);
			}
			htmlWidget->removeItem(item);
		}
	}
}
void MainWindow::slotCopyActionTriggered(BObject* object, const BValue& value)
{
	if (BHtmlWidget* htmlWidget = (BHtmlWidget*)_pageTabWidget->current())
	{
		if (BHtmlItem* item = htmlWidget->selectedItem())
		{
			BSystem::SetClippedValue(item->clone());
		}
	}
}
void MainWindow::slotPasteActionTriggered(BObject* object, const BValue& value)
{
	if (BHtmlWidget* htmlWidget = (BHtmlWidget*)_pageTabWidget->current())
	{
		BHtmlItem* selectedItem = htmlWidget->selectedItem();
		BHtmlItem* item = BSystem::GetClippedValue();
		if (selectedItem && item)
		{
			selectedItem->addChild(item);
			refreshTreeItem(selectedItem);
		}
	}
}

void MainWindow::slotHtmlWidgetFramed(BHtmlWidget* htmlWidget, const BValue& value)
{
	BPainter painter(htmlWidget);
	BMenu* viewMenu = _viewMenuButton->menu();
	if (viewMenu->action("show-links")->checked())
	{
		paintLinks(htmlWidget->body(), painter);
	}
	BColor color = painter.color("item-selected");
	if (!_editableButton->checked())
	{
		BReal time = bTime() - _selectTick;
		if (time < 2)
			color.a() = BByte((1 - time) * 255);
		else
			color.a() = 0;
	}
	if (color.a())
	{
		painter.setLineStipple(0xAAAA);
		const BHtmlItemArray& selection = htmlWidget->selection();
		for (int i = 0; i < selection.size(); i++)
		{
			BRect itemRect = selection[i]->rect();
			painter.setColor(color);
			painter.drawRect(itemRect);
		}
		painter.setLineStipple(0x0000);
	}
	if (htmlWidget->editable())
	{
		paintMarks(htmlWidget->body(), painter);

		BHtmlItem* hoveredItem = htmlWidget->query("hovered-item");

		State state = painter.state();
		painter.setLineWidth(1.0f);
		painter.setLineStipple(0xAAAA);
		for (int i = 0; i < htmlWidget->selectedItemCount(); i++)
		{
			BHtmlItem* item = htmlWidget->selectedItem(i);
			if (item == hoveredItem)
				continue;
			painter.setColor(Color_Wire, state | State_Selected);
			if (item->display() > BHtmlItem::Display_Inline_Block)
			{
				paintUnderLine(item, painter);
			}
			else
			{
				painter.drawRect(item->rect());
			}
		}
		if (hoveredItem)
		{
			painter.setColor(Color_Wire, state | State_Hovered);
			if (hoveredItem->display() > BHtmlItem::Display_Inline_Block)
			{
				paintUnderLine(hoveredItem, painter);
			}
			else
			{
				painter.drawRect(hoveredItem->rect());
			}
		}
		painter.setLineStipple(0x0000);
	}

}
void MainWindow::slotHtmlItemSelected(BObject* object, const BValue& value)
{
	if (BTreeItem* item = _htmlTreeWidget->itemOfAsset(value))
	{
		_htmlTreeWidget->setItemSelected(item, true);
		_htmlTreeWidget->scrollToItem(item);
	}
	_selectTick = bTime();
}
void MainWindow::slotHtmlItemClicked(BHtmlWidget* htmlWidget, const BValue& value)
{
	if (htmlWidget->editable())
		return;
	BHtmlItem* item = value;
	if (item && item->name() == 'a')
	{
		const BString& name = htmlWidget->name();
		const BString& href = item->attrib("href");
		if (!href.beginWith('#'))
		{
			BString currentPath = BApplication::currentPath();
			BString fileName = name.path();
			fileName << '/' << href;
			openHtmlFile(fileName);
		}
	}
}
void MainWindow::slotHtmlItemRightClicked(BHtmlWidget* htmlWidget, const BValue& value)
{
	BHtmlItem* item = value;
	const BPoint& pos = BCursor::GetPos(this);
	if (htmlWidget->editable())
	{
		_tableMenu->action("add row")->setEnabled(false);
		_tableMenu->action("insert row")->setEnabled(false);
		_tableMenu->action("remove row")->setEnabled(false);
		_tableMenu->action("add column")->setEnabled(false);
		_tableMenu->action("insert column")->setEnabled(false);
		_tableMenu->action("remove column")->setEnabled(false);
		if (item && item->name() == "table")
		{
			_tableMenu->action("add row")->setEnabled(true);
			_tableMenu->action("add column")->setEnabled(true);
			_tableMenu->setPos(pos);
			_tableMenu->popup();
		}
		else if (item && item->name() == "tr")
		{
			_tableMenu->action("add row")->setEnabled(true);
			_tableMenu->action("add column")->setEnabled(true);
			_tableMenu->action("insert row")->setEnabled(true);
			_tableMenu->action("remove row")->setEnabled(true);
			_tableMenu->setPos(pos);
			_tableMenu->popup();
		}
		else if (item && item->name() == "td")
		{
			_tableMenu->action("add row")->setEnabled(true);
			_tableMenu->action("insert row")->setEnabled(true);
			_tableMenu->action("remove row")->setEnabled(true);
			_tableMenu->action("add column")->setEnabled(true);
			_tableMenu->action("insert column")->setEnabled(true);
			_tableMenu->action("remove column")->setEnabled(true);
			_tableMenu->setPos(pos);
			_tableMenu->popup();
		}
		else
		{
			_pageMenu->setPos(pos);
			_pageMenu->popup();
		}
	}
}
void MainWindow::slotHtmlItemChanged(BHtmlWidget* htmlWidget, const BValue& value)
{
	signTitleChanged(htmlWidget, true);
}

void MainWindow::slotMenuAddActionClicked(BObject* object, const BValue& value)
{
	BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(_pageTabWidget->current());
	if (!htmlWidget)
		return;

	BAction* action = value;
	BHtmlItem* selectedItem = htmlWidget->selectedItem();
	if (selectedItem && action)
	{
		BString tagName = action->text();
		if (tagName == "text")
			tagName.reset();
		BString tagClass;
		if (action->text() == "custom")
		{
			if (!_customTagDialog->execute())
				return;
			tagName = _customTagDialog->tagName();
			tagClass = _customTagDialog->tagClass();
		}
		BHtmlItem* item = new BHtmlItem(tagName);
		if (tagClass.size())
			item->setAttrib("class", tagClass);
		if (selectedItem->name().empty())
		{
			BHtmlItem* parentItem = selectedItem->parent();
			BRange range = selectedItem->selectedRange();
			if (range.empty())
			{
				parentItem->addChild(item);
			}
			else
			{
				BString text = selectedItem->text();
				auto begin = text.seek(range.min());
				auto end = text.seek(range.max());

				BString afterText = text.substr(end);
				if (afterText.size())
				{
					parentItem->insertText(selectedItem->index() + 1, afterText);
					text.erase(end, text.end());
				}

				BString selectedText = text.substr(begin);
				item->setText(selectedText);
				parentItem->insertChild(selectedItem->index() + 1, item);

				text.erase(begin, text.end());
				selectedItem->setText(text);
			}
			htmlWidget->setSelection(item);
			refreshTreeItem(parentItem);
		}
		else
		{
			BRange range = selectedItem->selectedRange();
			if (range.empty())
			{
				selectedItem->addChild(item);
			}
			else
			{
				BString text = selectedItem->text();
				auto begin = text.seek(range.min());
				auto end = text.seek(range.max());

				BString afterText = text.substr(end);
				if (afterText.size())
				{
					selectedItem->insertText(0, afterText);
					text.erase(end, text.end());
				}

				BString selectedText = text.substr(begin);
				item->setText(selectedText);
				selectedItem->insertChild(0, item);

				text.erase(begin, text.end());
				selectedItem->setText(text);
			}
			htmlWidget->setSelection(item);
			refreshTreeItem(selectedItem);
		}
		signTitleChanged(htmlWidget, true);
	}
}
void MainWindow::slotMenuPrependActionClicked(BObject* object, const BValue& value)
{
	BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(_pageTabWidget->current());
	if (!htmlWidget)
		return;

	BHtmlItem* selectedHtmlItem = htmlWidget->selectedItem();
	BAction* action = value;
	if (selectedHtmlItem && action)
	{
		BHtmlItem* parentItem = selectedHtmlItem->parent();
		if (!parentItem)
			return;
		BString tagName = action->text();
		BString tagClass;
		if (action->text() == "custom")
		{
			if (!_customTagDialog->execute())
				return;
			tagName = _customTagDialog->tagName();
			tagClass = _customTagDialog->tagClass();
		}
		BHtmlItem* item = new BHtmlItem(tagName);
		if (tagClass.size())
			item->setAttrib("class", tagClass);
		parentItem->insertChild(selectedHtmlItem->index(), item);
		if (BTreeItem* treeItem = _htmlTreeWidget->itemOfAsset(parentItem))
		{
			BTreeItem* selectedTreeItem = treeItem->childOfAsset(selectedHtmlItem);
			treeItem->insertChild(selectedTreeItem->index(), createTreeItem(item));
		}
		htmlWidget->setSelection(item);
		signTitleChanged(htmlWidget, true);
	}
}
void MainWindow::slotMenuAppendActionClicked(BObject* object, const BValue& value)
{
	BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(_pageTabWidget->current());
	if (!htmlWidget)
		return;
	if (BHtmlItem* selectedHtmlItem = htmlWidget->selectedItem())
	{
		BHtmlItem* parentItem = selectedHtmlItem->parent();
		BAction* action = value;
		if (action && parentItem)
		{
			BString tagName = action->text();
			BString tagClass;
			if (action->text() == "custom")
			{
				if (!_customTagDialog->execute())
					return;
				tagName = _customTagDialog->tagName();
				tagClass = _customTagDialog->tagClass();
			}
			BHtmlItem* item = new BHtmlItem(tagName);
			if (tagClass.size())
				item->setAttrib("class", tagClass);
			parentItem->insertChild(selectedHtmlItem->index() + 1, item);
			if (BTreeItem* treeItem = _htmlTreeWidget->itemOfAsset(parentItem))
			{
				BTreeItem* selectedTreeItem = treeItem->childOfAsset(selectedHtmlItem);
				treeItem->insertChild(selectedTreeItem->index() + 1, createTreeItem(item));
			}
			htmlWidget->setSelection(item);
		}
		signTitleChanged(htmlWidget, true);
	}
}
void MainWindow::slotMenuConvertActionClicked(BObject* object, const BValue& value)
{
	BHtmlWidget* htmlWidget = dynamic_cast<BHtmlWidget*>(_pageTabWidget->current());
	if (!htmlWidget)
		return;
	if (BHtmlItem* htmlItem = htmlWidget->selectedItem())
	{
		if (BAction* action = value)
		{
			if (action->text() == "custom")
			{
				if (!_customTagDialog->execute())
					return;
				htmlItem->setName(_customTagDialog->tagName());
				const BString& tagClass = _customTagDialog->tagClass();
				if (tagClass.size())
					htmlItem->setAttrib("class", tagClass);
			}
			else
			{
				htmlItem->setName(action->text());
			}
			signTitleChanged(htmlWidget, true);
		}
	}
}

void MainWindow::closeEvent(const BEvent& event)
{
	BMainWindow::closeEvent(event);
}

void MainWindow::updateEvent(const BEvent& event)
{
	if (BWidget* widget = _pageTabWidget->current())
	{
		_saveButton->setEnabled(widget->title().endWith('*'));
	}
	bool saveAll = false;
	for (int i = 0; i < _pageTabWidget->tabCount(); i++)
	{
		BWidget* widget = _pageTabWidget->tab(i);
		if (widget->title().endWith('*'))
		{
			saveAll = true;
			break;
		}
	}
	_saveAllButton->setEnabled(saveAll);
	if (BWidget* widget = _pageTabWidget->current())
	{
		if (widget->query("selected-items").valid())
		{
			if (event.now() - _selectTick < 1)
			{
				widget->fresh();
			}
		}
	}
}

void MainWindow::styleEvent(const BEvent& event)
{
	BMainWindow::styleEvent(event);
	const BStyle* style = event.value();

	_openButton->setIcon(style->icon("open"));
	_saveButton->setIcon(style->icon("save"));
	_saveAllButton->setIcon(style->icon("save-all"));
	_prevButton->setIcon(style->icon("prev"));
	_nextButton->setIcon(style->icon("next"));
	_headFreshButton->setIcon(style->icon("fresh"));
	_editableButton->setIcon(style->icon("editable"));

	_removeAction->setIcon(style->icon("remove"));
	_cutAction->setIcon(style->icon("cut"));
	_copyAction->setIcon(style->icon("copy"));
	_pasteAction->setIcon(style->icon("paste"));

	_htmlIcon = style->icon("html-icon");
	_textIcon = style->icon("text-edit-icon");
	_treeIcon = style->icon("xml-tree-icon");

	_linkIcon = style->icon("link");
	_normalImage = style->image("normal");
	_dirtyImage = style->image("dirty");
	_emptyImage = style->image("empty");

	if (BMenu* menu = _itemStateButton->menu())
	{
		menu->clear();
		menu->addAction(_normalImage, "normal");
		menu->addAction(_dirtyImage, "dirty");
		menu->addAction(_emptyImage, "empty");
	}

	for (int i = 0; i < _fileListWidget->itemCount(); i++)
	{
		freshHeadItemIcons(_fileListWidget->item(i));
	}

	for (int i = 0; i < _pageTabWidget->tabCount(); i++)
	{
		BWidget* widget = _pageTabWidget->tab(i);
		if (dynamic_cast<BHtmlWidget*>(widget))
		{
			widget->setIcon(_htmlIcon);
			continue;
		}
		if (dynamic_cast<BTextEdit*>(widget))
		{
			widget->setIcon(_textIcon);
			continue;
		}
		if (dynamic_cast<BTreeWidget*>(widget))
		{
			widget->setIcon(_treeIcon);
			continue;
		}
	}

	_openButton->setTips(style->text("tips-open"));
	_saveButton->setTips(style->text("tips-save"));
	_saveAllButton->setTips(style->text("tips-save-all"));
	_prevButton->setTips(style->text("tips-prev"));
	_nextButton->setTips(style->text("tips-next"));
	_headFreshButton->setTips(style->text("tips-fresh"));
	_editableButton->setTips(style->text("tips-edit-mode"));

	_removeAction->setTips(style->text("tips-remove"));
	_cutAction->setTips(style->text("tips-cut"));
	_copyAction->setTips(style->text("tips-copy"));
	_pasteAction->setTips(style->text("tips-paste"));

}
